package com.huoyun.user.action;

import java.io.IOException;
import java.util.Date;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.springframework.security.authentication.encoding.PasswordEncoder;

import com.huoyun.base.action.BaseAction;
import com.huoyun.user.bean.PasswordLink;
import com.huoyun.user.bean.User;
import com.huoyun.user.service.PasswordLinkService;
import com.huoyun.user.service.UserService;
import com.huoyun.util.SendUtil;
import com.huoyun.util.bean.MailSenderInfo;
import com.opensymphony.xwork2.ActionContext;

public class PasswordAction extends BaseAction {
	private static final long serialVersionUID = 1L;
	
	private static final Log log = LogFactory.getLog(UserAction.class);
	
	/**
	 * salt 的长度
	 */
	private static final int SALT_LENGTH = 8;
	/**
	 * 密码加密器
	 */
	private PasswordEncoder passwordEncoder;
	/**
	 * 待检查的用户名
	 * 忘记密码时，第一步检查用户名是否存在
	 */
	private String usernameCheck;
	/**
	 * 管理user的service
	 */
	private UserService userService;
	/**
	 * 验证码
	 */
	private String verifyCode;
	/**
	 * 用户id
	 */
	private long userId;
	/**
	 * 新密码
	 */
	private String newPassword;
	/**
	 * 邮箱地址
	 */
	private String email;
	/**
	 * 管理PasswordLink的service
	 */
	private PasswordLinkService passwordLinkService;
	/**
	 * 判断修改密码是否成功
	 * 0: 不成功; 99: 成功
	 */
	private int isSuccessful;
	
	/**
	 * 以ajax的方式检查用户名是否存在
	 * @return
	 * @throws IOException
	 * @author ChengXin
	 */
	public String ajaxCheckExist() throws IOException
	{
		this.setResultMsg("false");
		
		if(StringUtils.isNotEmpty(usernameCheck))
		{
			try{
				User user = userService.getUserByUsername(usernameCheck);
			
				if(user != null)
				{
					this.setResultMsg("true");
				}
			}catch (Exception e) {
				log.error("查询用户失败！UserAction - [checkUser]: Exception catched:" + e.getMessage());
			}
		
		}
		
		HttpServletResponse response = (HttpServletResponse)ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
		
		try
		{
			response.getWriter().print(this.getResultMsg());
		}catch (IOException e) {
			log.error("校验用户【"+ usernameCheck +"】输出流发生错误！原因：" + e.fillInStackTrace());
			
			throw e;
		}
		return null;
	}
	
	/**
	 * 校验用户名是否存在
	 * 校验验证码是否在正确
	 * @return true|false
	 * @throws IOException
	 * @author ChengXin
	 */
	public String checkExist() throws IOException
	{
		if(StringUtils.isNotEmpty(usernameCheck))
		{
			try{
				User user = userService.getUserByUsername(usernameCheck);
			
				if(user == null)
				{
					this.setResultMsg("该用户名不存在，请输入正确的用户名");
					return ERROR;
				}
				else if (verifyCode == null)
				{
					this.setResultMsg("请输入验证码");
					return INPUT;
				}
				else
				{
					String sessionVerifyCode = (String)getSession().getAttribute("verifyCode");
					//从session取出验证码后，将session中存放的验证码置为空
					getSession().setAttribute("verifyCode", "");
					//对验证码进行校验
					if(!(verifyCode.toLowerCase()).equals(sessionVerifyCode.toLowerCase()))
					{
						this.setResultMsg("验证码输入错误");
						
						return INPUT;
					}
					else
					{
						this.userId = user.getId();
					}
				}
			}catch (Exception e) {
				log.error("查询用户失败！UserAction - [checkUser]: Exception catched:" + e.getMessage());
			}
		}
		else
		{
			this.setResultMsg("请输入用户名");
			return ERROR;
		}
		
		return SUCCESS;
	}
	
	/**
	 * 向安全邮箱发送密码修改邮件
	 * 将用户id、link创建时间、linkId拼接后用MD5加密，将密文sec连接到连接尾部
	 * @return
	 * @author ChengXin
	 */
	public String sendChangePasswordEmail()
	{
		long userId = Long.parseLong(getRequest().getParameter("userId"));
		
		// 删除当前用户的旧链接
		passwordLinkService.deleteByUserId(userId);
		
		email = userService.getUserById(userId).getEmail();
		
		MailSenderInfo mailInfo = new MailSenderInfo();
		//发邮件
	    mailInfo.setMailServerHost("smtp.126.com");
	    mailInfo.setMailServerPort("25");
	    mailInfo.setValidate(true);
	    mailInfo.setUserName("huoyunwang123@126.com");
	    mailInfo.setPassword("huoyun123");//您的邮箱密码
	    mailInfo.setFromAddress("huoyunwang123@126.com");
	    
	    //将加密后的临时链接存入_password_link表中
	    PasswordLink link = new PasswordLink();
	    Date currentTime = new Date();
	    passwordLinkService.saveAll(link);
	    String passwordMD5 = passwordEncoder.encodePassword(userId+currentTime.toString(), link.getId());
	    String editLink = "http://localhost:8080/huoyun/user/passwordGetBack.action?userId="+userId+"&lkid="+link.getId()+"&sec="+passwordMD5;
	    link.setCreateTime(currentTime);
	    link.setUrl(editLink);
	    link.setUserId(userId);
	    passwordLinkService.updateAll(link);
	    
	    //发送邮件
	    mailInfo.setSubject("运策网密码找回");	    
	    String htmlContent = "<div id='divFMContentBody' style='white-space:normal; word-break:break-all; width: 600px;'>" +
	    		"<p align='center'><strong>运策网密码找回</strong></p>" +
	    		"<hr>" +
	    		"<p>亲爱的用户，您好：<br><br>" +
	    		"您申请认证邮箱找回密码请点击以下链接，即可生效！<br>" +
	    		"（注：链接有效时间为30分钟，超时链接失效请重新进行申请操作）<br>" +
	    		"<a href='" + editLink + "' target='_blank'>" + editLink + "</a>" +
	    		"</p>" +
	    		"<p>如今后有任何问题，请您登录：<a href='http://xxxx' target='_blank'>http://xxxx</a> 进行询问及反馈，感谢您的支持。</p>" +
	    		"<p>运策网郑重提醒！！！！<br>" +
	    		"在您交易中，如有任何消息提示，告知您获奖。请不要相信。那是一些不法份子假冒官方，<br>" +
	    		"以各种中奖活动为由，让玩家进入假冒官网页面，欺骗您的钱财以及个人账号信息。</p>" +
	    		"<p>对此，请您记住以下鉴别特征：<br>" +
	    		"1.我们运策网所有的网站页面域名都是以xxxx.com结尾的。<br>" +
	    		"2.运策网的唯一官方地址：<a href='http://xxxx' target='_blank'>xxxx</a>，旗下各业务的官方网址皆以运策网的官网中链接为准。<br>" +
	    		"</p>" +
	    		"</div>";
	    mailInfo.setContent(htmlContent);
	    
	    mailInfo.setToAddress(email);
	    SendUtil.sendHtmlMail(mailInfo);
	    
		return SUCCESS;
	}
	
	/**
	 * 修改密码
	 * @return SUCCESS
	 * @author ChengXin
	 */
	public String setNewPassword()
	{
		isSuccessful = 0;
		
		userId = Long.parseLong(getRequest().getParameter("userId"));
		long linkId = Long.parseLong(getRequest().getParameter("lkid"));
		
		String sec = getRequest().getParameter("sec");
		if (StringUtils.isNotEmpty(sec))
		{
			PasswordLink passwordLink = passwordLinkService.getPasswordLinkById(linkId);
			if (passwordLink == null)
			{
				this.setResultMsg("此链接已经失效，无法修改密码");
				return "LINKERROR";
			}
			else
			{
				String secOriginal = passwordEncoder.encodePassword(userId+passwordLink.getCreateTime().toString(), linkId);
				if (secOriginal.compareTo(sec) == 0)
				{
					if (userId != passwordLink.getUserId())
					{
						this.setResultMsg("此链接已经失效，无法修改密码");
						return "LINKERROR";
					}
					else
					{
						Date currentDate = new Date();
						long timeGap = (currentDate.getTime() - passwordLink.getCreateTime().getTime())/(1000*60);
						if (timeGap > 30 || timeGap < -30)
						{
							passwordLinkService.deleteById(linkId);
							this.setResultMsg("此链接已经失效，无法修改密码");
							return "TIMEERROR";
						}
						else
						{
							//获取一个随机的字符串salt
							String randSalt = RandomStringUtils.random(SALT_LENGTH, true, true);
							
							//将用户输入的密码和随机生成的salt联合起来进行md5加密
							String saltPassword = passwordEncoder.encodePassword(newPassword, randSalt);
							
							userService.changePassword(userId, saltPassword);
							userService.updateSalt(userId, randSalt);
							passwordLinkService.deleteById(linkId);

							this.setResultMsg("修改密码成功！");
							isSuccessful = 99;
							return SUCCESS;
						}
					}
				}
				else
				{
					this.setResultMsg("此链接已经失效，无法修改密码");
					return "SECERROR";
				}
			}
		}
		else
		{
			this.setResultMsg("此链接已经失效，无法修改密码");
			return "SECERROR";
		}
	}

	public String getUsernameCheck() {
		return usernameCheck;
	}

	public void setUsernameCheck(String usernameCheck) {
		this.usernameCheck = usernameCheck;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public String getVerifyCode() {
		return verifyCode;
	}

	public void setVerifyCode(String verifyCode) {
		this.verifyCode = verifyCode;
	}

	public long getUserId() {
		return userId;
	}

	public void setUserId(long userId) {
		this.userId = userId;
	}

	public PasswordEncoder getPasswordEncoder() {
		return passwordEncoder;
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}

	public String getNewPassword() {
		return newPassword;
	}

	public void setNewPassword(String newPassword) {
		this.newPassword = newPassword;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public PasswordLinkService getPasswordLinkService() {
		return passwordLinkService;
	}

	public void setPasswordLinkService(PasswordLinkService passwordLinkService) {
		this.passwordLinkService = passwordLinkService;
	}

	public int getIsSuccessful() {
		return isSuccessful;
	}

	public void setIsSuccessful(int isSuccessful) {
		this.isSuccessful = isSuccessful;
	}
}
